﻿using Sdcb.SparkDesk;
using TokenApi.Contract;
using TokenApi.Contract.Domain;
using TokenApi.Service.Contract;
using TokenApi.Service.Exceptions;

namespace TokenApi.Service.Service;

public sealed class SparkDeskService : IChatService
{
    public const string Name = "SparkDesk";

    public async IAsyncEnumerable<CompletionResult> CompletionsAsync<T>(ChatCompletionDto<T>? dto,
        ChatChannel data = null)
    {
        var key = data?.Key ?? throw new ArgumentNullException(nameof(data.Key));

        var keys = key.Split("|", StringSplitOptions.RemoveEmptyEntries);

        // 固定Key的格式为 appId|appKey|appSecret
        var client = new SparkDeskClient(keys[0], keys[1], keys[2]);

        ModelVersion modelVersion;
        if (dto?.model == "SparkDesk-v3.5")
        {
            modelVersion = ModelVersion.V3_5;
        }
        else if (dto?.model == "SparkDesk-v3.1")
        {
            modelVersion = ModelVersion.V3;
        }
        else if (dto?.model == "SparkDesk-v1.5")
        {
            modelVersion = ModelVersion.V1_5;
        }
        else if (dto?.model == "SparkDesk-v2.1")
        {
            modelVersion = ModelVersion.V2;
        }
        else
        {
            throw new NotModelException(dto?.model);
        }

        // 判断t是否为ChatVisionCompletionRequestMessage
        if (dto.messages is List<ChatVisionCompletionRequestMessage> visions)
        {
            throw new ModelNotSupportedException($"model:{dto.model} 未支持Vision功能");
        }


        if (dto.messages is List<ChatCompletionRequestMessage> chats)
        {
            int topK;
            if (dto.top_p.HasValue)
            {
                double incrementedValue = dto.top_p.Value + 1;
                topK = Convert.ToInt32(Math.Round(incrementedValue));
            }
            else
            {
                topK = 0; // or any default value you want
            }

            var results = chats.Select(x => new ChatMessage(x.role, x.content)).ToArray();
            await foreach (StreamedChatResponse msg in client.ChatAsStreamAsync(modelVersion,
                               results, new ChatRequestParameters
                               {
                                   ChatId = Guid.NewGuid().ToString("N"),
                                   MaxTokens = dto.max_tokens,
                                   Temperature = dto.temperature,
                                   TopK = topK,
                               }))
            {
                yield return new CompletionResult(msg.Text);
            }
        }
    }
}